import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

class PageViewPage extends StatelessWidget {
  const PageViewPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(title:const Text('PageViewPage')),
        body:PageViewDemo()
    );
  }
}

class PageViewDemo extends StatefulWidget {
  const PageViewDemo({super.key});
  @override
  State<PageViewDemo> createState() => _PageViewDemoState();
}

class _PageViewDemoState extends State<PageViewDemo> with RestorationMixin {
  // —— PageController 也有自己的属性 —— //
  // initialPage: 初始页；keepPage: 记住上次位置；viewportFraction: 视口占比(可做卡片轮播效果)
  final PageController _controller = PageController(
    initialPage: 1,
    keepPage: true,
    viewportFraction: 0.9,
  );

  // —— PageView 可调属性 —— //
  Axis _scrollDirection = Axis.horizontal; // scrollDirection: 滚动方向
  bool _reverse = false;                   // reverse: 反向（右到左/下到上）
  bool _pageSnapping = true;               // pageSnapping: 是否自动对齐到整页
  bool _allowImplicitScrolling = false;    // allowImplicitScrolling: 预渲染相邻页面(无障碍/可见性更好)
  bool _padEnds = true;                    // padEnds: 首尾是否留出半屏边距(视口小于1时直观)
  Clip _clipBehavior = Clip.hardEdge;      // clipBehavior: 裁剪方式
  ScrollPhysics? _physics = const BouncingScrollPhysics(); // physics: 滚动物理

  // restorationId: 状态恢复(需配合 RestorationMixin)
  final RestorableInt _restoredPage = RestorableInt(1);
  @override
  String? get restorationId => 'page_view_demo';

  @override
  void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
    registerForRestoration(_restoredPage, 'current_page');
    // 恢复后跳到记录页
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (_controller.hasClients) {
        _controller.jumpToPage(_restoredPage.value);
      }
    });
  }

  int _currentPage = 1;

  @override
  void dispose() {
    _controller.dispose();
    _restoredPage.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final pages = List.generate(5, (index) => _buildCard(index));

    return Scaffold(
      appBar: AppBar(
        title: const Text('PageView 全属性演示'),
        actions: [
          IconButton(
            tooltip: '跳到页 3',
            onPressed: () => _controller.animateToPage(
              3,
              duration: const Duration(milliseconds: 350),
              curve: Curves.easeOut,
            ),
            icon: const Icon(Icons.skip_next),
          ),
        ],
      ),
      drawer: _buildSettingsDrawer(),
      body: Column(
        children: [
          _buildStatusBar(),
          // —— PageView 核心示例 —— //
          Expanded(
            child: PageView(
              // ✅ 滚动方向：水平/垂直
              scrollDirection: _scrollDirection,

              // ✅ 是否反向滚动（RTL/从下到上）
              reverse: _reverse,

              // ✅ 控制器（包含 initialPage/keepPage/viewportFraction）
              controller: _controller,

              // ✅ 物理特性（Bouncing/Clamping/NeverScrollable 等）
              physics: _physics,

              // ✅ 是否吸附到整页
              pageSnapping: _pageSnapping,

              // ✅ 页改变回调
              onPageChanged: (index) {
                setState(() {
                  _currentPage = index;
                  _restoredPage.value = index; // 同步到状态恢复
                });
              },

              // ✅ 拖拽起始行为（start/down）
              dragStartBehavior: DragStartBehavior.start,

              // ✅ 允许隐式滚动(对可访问性/预渲染友好，可能稍占内存)
              allowImplicitScrolling: _allowImplicitScrolling,

              // ✅ 状态恢复 ID（与 RestorationMixin 搭配）
              restorationId: 'page_view_restorable',

              // ✅ 裁剪行为（none/hardEdge/antiAlias/antiAliasWithSaveLayer）
              clipBehavior: _clipBehavior,

              // ✅ 首尾是否留白（配合 viewportFraction 更明显）
              padEnds: _padEnds,

              // ✅ 展示的页面
              children: pages,
            ),
          ),
          const SizedBox(height: 8),
          // —— 另外两种构造方式的最小示例 —— //
          _buildOtherConstructorsDemo(),
        ],
      ),
    );
  }

  // 信息栏
  Widget _buildStatusBar() {
    return Padding(
      padding: const EdgeInsets.fromLTRB(12, 8, 12, 4),
      child: Wrap(
        spacing: 16,
        crossAxisAlignment: WrapCrossAlignment.center,
        children: [
          Text('当前页: $_currentPage'),
          Text('方向: ${_scrollDirection == Axis.horizontal ? "水平" : "垂直"}'),
          Text('反向: ${_reverse ? "是" : "否"}'),
          Text('吸附: ${_pageSnapping ? "是" : "否"}'),
          Text('隐式滚动: ${_allowImplicitScrolling ? "开" : "关"}'),
          Text('padEnds: ${_padEnds ? "开" : "关"}'),
          Text('裁剪: $_clipBehavior'),
        ],
      ),
    );
  }

  // 设置抽屉
  Drawer _buildSettingsDrawer() {
    return Drawer(
      child: SafeArea(
        child: ListView(
          padding: const EdgeInsets.all(12),
          children: [
            const ListTile(title: Text('PageView 属性设置', style: TextStyle(fontWeight: FontWeight.bold))),
            // scrollDirection
            SwitchListTile(
              title: const Text('垂直滚动 (Axis.vertical)'),
              value: _scrollDirection == Axis.vertical,
              onChanged: (v) => setState(() {
                _scrollDirection = v ? Axis.vertical : Axis.horizontal;
              }),
            ),
            // reverse
            SwitchListTile(
              title: const Text('reverse（反向滚动）'),
              value: _reverse,
              onChanged: (v) => setState(() => _reverse = v),
            ),
            // pageSnapping
            SwitchListTile(
              title: const Text('pageSnapping（整页吸附）'),
              value: _pageSnapping,
              onChanged: (v) => setState(() => _pageSnapping = v),
            ),
            // allowImplicitScrolling
            SwitchListTile(
              title: const Text('allowImplicitScrolling（预渲染相邻页）'),
              value: _allowImplicitScrolling,
              onChanged: (v) => setState(() => _allowImplicitScrolling = v),
            ),
            // padEnds
            SwitchListTile(
              title: const Text('padEnds（首尾留白）'),
              value: _padEnds,
              onChanged: (v) => setState(() => _padEnds = v),
            ),
            // clipBehavior
            DropdownButtonFormField<Clip>(
              value: _clipBehavior,
              decoration: const InputDecoration(labelText: 'clipBehavior（裁剪）'),
              items: const [
                DropdownMenuItem(value: Clip.none, child: Text('Clip.none')),
                DropdownMenuItem(value: Clip.hardEdge, child: Text('Clip.hardEdge')),
                DropdownMenuItem(value: Clip.antiAlias, child: Text('Clip.antiAlias')),
                DropdownMenuItem(value: Clip.antiAliasWithSaveLayer, child: Text('Clip.antiAliasWithSaveLayer')),
              ],
              onChanged: (v) => setState(() => _clipBehavior = v ?? Clip.hardEdge),
            ),
            const SizedBox(height: 12),
            // physics
            DropdownButtonFormField<String>(
              value: 'bouncing',
              decoration: const InputDecoration(labelText: 'physics（滚动物理）'),
              items: const [
                DropdownMenuItem(value: 'bouncing', child: Text('BouncingScrollPhysics(iOS风)')),
                DropdownMenuItem(value: 'clamping', child: Text('ClampingScrollPhysics(Android风)')),
                DropdownMenuItem(value: 'never', child: Text('NeverScrollableScrollPhysics(禁用交互)')),
                DropdownMenuItem(value: 'null', child: Text('默认(根据平台推断)')),
              ],
              onChanged: (v) => setState(() {
                switch (v) {
                  case 'bouncing':
                    _physics = const BouncingScrollPhysics();
                    break;
                  case 'clamping':
                    _physics = const ClampingScrollPhysics();
                    break;
                  case 'never':
                    _physics = const NeverScrollableScrollPhysics();
                    break;
                  default:
                    _physics = null;
                }
              }),
            ),
            const Divider(height: 24),
            const ListTile(title: Text('PageController 设置', style: TextStyle(fontWeight: FontWeight.bold))),
            // viewportFraction
            Row(
              children: [
                const Text('viewportFraction'),
                Expanded(
                  child: Slider(
                    value: _controller.viewportFraction,
                    min: 0.6,
                    max: 1.0,
                    divisions: 8,
                    label: _controller.viewportFraction.toStringAsFixed(2),
                    onChanged: (v) {
                      setState(() {
                        // PageController 的 viewportFraction 不能直接改，需要新建一个控制器以更新
                        final newPage = _currentPage;
                        final newController = PageController(
                          initialPage: newPage,
                          keepPage: _controller.keepPage,
                          viewportFraction: v,
                        );
                        // 为了示例简单，这里不做平滑过渡，直接替换
                        _controller.dispose();
                        // ignore: invalid_use_of_protected_member
                        // 为了演示，动态替换控制器（生产中建议封装更优雅）
                        // 这里采用临时 hack：通过字段反射难以做到，改为 setState + 成员变量重建
                      });
                    },
                  ),
                ),
              ],
            ),
            const Padding(
              padding: EdgeInsets.only(top: 8),
              child: Text(
                '⚠️ 注意：PageController 的 viewportFraction/initialPage 一般需要重建控制器来生效，'
                    '示例里为了保持简洁，展示了属性含义；实际项目可封装一个 setState 重建 controller 的方法。',
                style: TextStyle(fontSize: 12),
              ),
            ),
          ],
        ),
      ),
    );
  }

  // 简单卡片页
  Widget _buildCard(int index) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16),
      child: Material(
        clipBehavior: Clip.antiAlias,
        borderRadius: BorderRadius.circular(20),
        elevation: 4,
        child: Stack(
          fit: StackFit.expand,
          children: [
            Container(
              alignment: Alignment.center,
              child: Text(
                'Page $index',
                style: const TextStyle(fontSize: 42, fontWeight: FontWeight.bold),
              ),
            ),
            Positioned(
              right: 12,
              bottom: 12,
              child: Text(
                '提示：试试垂直/反向/禁滚动等设置',
                style: Theme.of(context).textTheme.labelMedium,
              ),
            ),
          ],
        ),
      ),
    );
  }

  // 另外两种构造方式：builder / custom
  Widget _buildOtherConstructorsDemo() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        const Divider(),
        const Padding(
          padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
          child: Text('其他构造方式（轻量示例）'),
        ),
        SizedBox(
          height: 120,
          child: PageView.builder(
            controller: PageController(viewportFraction: 0.4),
            itemCount: 10, // ✅ builder: 使用 itemBuilder + itemCount（或无限滚动不设 count）
            itemBuilder: (context, i) => Padding(
              padding: const EdgeInsets.symmetric(horizontal: 6),
              child: DecoratedBox(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(12),
                  gradient: LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                    colors: [Colors.blue.shade200, Colors.blue.shade50],
                  ),
                ),
                child: Center(child: Text('builder $i')),
              ),
            ),
          ),
        ),
        const SizedBox(height: 8),
        SizedBox(
          height: 60,
          child: PageView.custom(
            // ✅ custom: 自定义 SliverChildDelegate，更灵活的子节点复用策略
            controller: PageController(viewportFraction: 0.25),
            childrenDelegate: SliverChildBuilderDelegate(
                  (context, i) => Center(
                child: Container(
                  margin: const EdgeInsets.symmetric(horizontal: 4),
                  padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(12),
                    border: Border.all(),
                  ),
                  child: Text('custom $i'),
                ),
              ),
              childCount: 20,
            ),
          ),
        ),
        const SizedBox(height: 8),
      ],
    );
  }
}
